Attribute VB_Name = "WindowProcHookMod"
Option Explicit
Private Const cstrEbMode As String = "EbMode"
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal wndrpcPrev As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

'VBA Mode states
Public Enum VBMode
    vbmWait = 0
    vbmRun = 1
    vbmBreak = 2
End Enum

Private m_FDEbMode As FunctionDelegator
Private m_pCallEbMode As ICallVoidReturnLong

Sub Main()
Dim hinstVBA As Long
Dim pfn As Long
    'Determine if we're running in the VB5 IDE
    hinstVBA = GetModuleHandle("vba5.dll")
    If hinstVBA = 0 Then
        'If not, see if we're running the VB6 IDE
        hinstVBA = GetModuleHandle("vba6.dll")
    End If
    
    If hinstVBA Then
        pfn = GetProcAddress(hinstVBA, cstrEbMode)
        If pfn Then Set m_pCallEbMode = InitDelegator(m_FDEbMode, pfn)
    End If
    
    'Warn to not use this in a compiled Exe
    If pfn = 0 Then MsgBox _
          "WindowProc debugging isn't required outside the Visual Basic design environment.", _
          vbInformation
End Sub

Public Function UseDebugProc() As Boolean
    'We're debugging if:
    '1) We're in the IDE
    '2) VBA is in break mode on this thread
    If Not m_pCallEbMode Is Nothing Then
        If m_pCallEbMode.Call = vbmBreak Then
            'We're in break mode, so use the alternate procedure
            UseDebugProc = True
        End If
    End If
End Function

Public Function RedirectWindowProc(ByVal Hook As WindowProcHook, ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    RedirectWindowProc = Hook.WindowProc(hWnd, uMsg, wParam, lParam)
End Function
